package protocol

import (
	"bytes"
	"encoding/binary"
)

type binaryProtocol struct {
}

func (bp *binaryProtocol) ReadHeader(pkg []byte, header *RpcMsgHeader) bool {
	if header == nil {
		return false
	}

	//binary.Read(pkg, binary.BigEndian, header)

	hsize := binary.Size(header)
	if hsize == -1 {
		//TODO add log
		return false
	}

	if len(pkg) < hsize {
		//not have enought buffer size
		return false
	}

	header.Length = binary.BigEndian.Uint32(pkg[0:4])
	header.Type = binary.BigEndian.Uint32(pkg[4:8])
	return true
}

//FIXME 补全网络大小端转换
func (bp *binaryProtocol) ParseReqMsg(pkg []byte, header *RpcCallHeader) bool {
	if header == nil {
		return false
	}

	if CallHeadSize > len(pkg) {
		return false
	}

	reader := bytes.NewBuffer(pkg)
	err := binary.Read(reader, binary.BigEndian, header)
	if err != nil {
		//TODO record log
		return false
	}

	return true
}

func (bp *binaryProtocol) ParseRespMsg(pkg []byte, header *RpcCallRetHeader) bool {
	if header == nil {
		return false
	}

	//hsize := binary.Size(header)
	if RespHeadSize > len(pkg) {
		return false
	}

	reader := bytes.NewBuffer(pkg)
	err := binary.Read(reader, binary.BigEndian, header)
	if err != nil {
		//TODO record log
		return false
	}

	return true
}

func (bp *binaryProtocol) PackRespMsg(resp *ResponsePackage) ([]byte, int) {
	if resp == nil {
		return nil, 0
	}

	totallen := RespHeadSize + len(resp.Buffer)
	pkg := make([]byte, totallen)

	binary.BigEndian.PutUint32(pkg[0:], resp.Header.Length)
	binary.BigEndian.PutUint32(pkg[4:], resp.Header.Type)
	binary.BigEndian.PutUint32(pkg[8:], resp.Header.ServerID)
	//FIXME wkk 把这个改成64位了 记得配合修改
	binary.BigEndian.PutUint32(pkg[12:], resp.Header.CallID)
	binary.BigEndian.PutUint32(pkg[16:], resp.Header.ErrorCode)
	copy(pkg[RespHeadSize:], resp.Buffer)
	return pkg, totallen
}

func (bp *binaryProtocol) PackReqMsg(req *RequestPackage) ([]byte, int) {
	if req == nil {
		return nil, 0
	}

	totallen := CallHeadSize + len(req.Buffer)
	pkg := make([]byte, totallen)

	binary.BigEndian.PutUint32(pkg[0:], req.Header.Length)
	binary.BigEndian.PutUint32(pkg[4:], req.Header.Type)
	binary.BigEndian.PutUint64(pkg[8:], req.Header.ServiceUUID)
	binary.BigEndian.PutUint32(pkg[16:], req.Header.ServerID)
	//FIXME wkk 把这个改成64位了 记得配合修改
	binary.BigEndian.PutUint32(pkg[20:], req.Header.CallID)
	binary.BigEndian.PutUint32(pkg[24:], req.Header.MethodID)

	copy(pkg[CallHeadSize:], req.Buffer)
	return pkg, totallen
}
